package com.risen.project.excel.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.metadata.CellData;
import com.risen.project.excel.handler.DefaultExcelHeadCheckHandler;
import com.risen.project.excel.handler.ExcelHeadCheckHandler;
import com.risen.project.excel.handler.InvokeHandler;
import com.risen.project.excel.handler.ParamConvertHandler;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * @author taoym
 * @date 2022/3/29 9:18
 * @description 读取转换执行监听器 主要是应对读取excel内容后 需要将内容入库的需求
 */
public class ReadConvertInvokeListener<F, T, R> extends AbstractReadListener<F> {

    /**
     * 存储excel的每行数据
     */
    private List<F> dataList = new LinkedList<>();
    /**
     * 每读取行数 进行插入数据库
     */
    private final Integer batch;
    /**
     * bean转换策略 将F类型转换为T类型
     */
    private final ParamConvertHandler<F, T> paramConvertHandler;
    /**
     * 执行策略
     */
    private final InvokeHandler<T, R> invokeHandler;
    /**
     * 返回值列表
     */
    private final List<R> resultList = new LinkedList<>();

    @Override
    public void invokeHead(Map<Integer, CellData> headMap, AnalysisContext context) {
        // 调用父类的表头校验方法
        super.invokeHead(headMap, context);
    }

    @Override
    public void invoke(F data, AnalysisContext context) {
        if (dataList.size() >= batch) {
            // 先将表格解析出来的数据进行类型转换 然后在执行具体的方法
            R r = invokeHandler.invoke(paramConvertHandler.convert(dataList));
            resultList.add(r);
            // 清空数据集合
            dataList = new LinkedList<>();
        }
        dataList.add(data);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        if (dataList != null && dataList.size() > 0) {
            R r = invokeHandler.invoke(paramConvertHandler.convert(dataList));
            resultList.add(r);
        }
    }

    public ReadConvertInvokeListener(Integer batch, ParamConvertHandler<F, T> paramConvertHandler, InvokeHandler<T, R> invokeHandler) {
        this.batch = batch;
        this.paramConvertHandler = paramConvertHandler;
        this.invokeHandler = invokeHandler;
    }

    public ReadConvertInvokeListener(Integer batch, ParamConvertHandler<F, T> paramConvertHandler, InvokeHandler<T, R> invokeHandler, Class<F> tClass) {
        this.batch = batch;
        super.setCheckHandler(new DefaultExcelHeadCheckHandler());
        this.paramConvertHandler = paramConvertHandler;
        this.invokeHandler = invokeHandler;
        super.settClass(tClass);
    }

    public ReadConvertInvokeListener(Integer batch, ExcelHeadCheckHandler headCheckHandler, ParamConvertHandler<F, T> paramConvertHandler, InvokeHandler<T, R> invokeHandler, Class<F> tClass) {
        this.batch = batch;
        super.setCheckHandler(headCheckHandler);
        this.paramConvertHandler = paramConvertHandler;
        this.invokeHandler = invokeHandler;
        super.settClass(tClass);
    }

    public List<R> getResultList() {
        return resultList;
    }
}
